package cn.tj.wenda.cloud.bas.service.impl;

import cn.tj.wenda.cloud.bas.entity.BasTenant;
import cn.tj.wenda.cloud.bas.mapper.BasTenantMapper;
import cn.tj.wenda.cloud.bas.service.BasTenantService;
import cn.tj.wenda.cloud.exception.BusinessException;
import cn.tj.wenda.cloud.util.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;

import cn.tj.wenda.cloud.entity.LoginUserInfo;
import tk.mybatis.mapper.entity.Example;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;

/**
 * @author Wenda
 */
@Component
@Scope("prototype")
public class BasTenantServiceImpl implements BasTenantService {

    @Autowired
    BasTenantMapper basTenantMapper;
    
    @Autowired
    DicMessage dicMessage;
    
    @Override
    public PageInfo<BasTenant> getBasTenantList(int page, int limit, String params) {
        Example ex = new Example(BasTenant.class);
        ex.setOrderByClause("updtime DESC,addtime DESC");

        if (!StringUtils.isEmpty(params)) {
			QueryParam queryParam = QueryParam.parseObject(params);
            //中文全称
            String fullname = queryParam.getString("fullname");
            //英文全称
            String efullname = queryParam.getString("efullname");
            //状态
            String status = queryParam.getString("status");

			Example.Criteria criteria = ex.or();
            if (!StringUtils.isEmpty(fullname)) {
                criteria.andLike("fullname","%" + fullname + "%");
            }
            if (!StringUtils.isEmpty(efullname)) {
				criteria.andLike("efullname","%" + efullname + "%");
            }
            if (!StringUtils.isEmpty(status)) {
				criteria.andEqualTo("status",status);
            }
        }
        PageHelper.startPage(page, limit, true);
        List<BasTenant> basTenants = basTenantMapper.selectByExample(ex);
        return new PageInfo<BasTenant>(basTenants);
    }

    @Override
    public BasTenant selectByPrimaryKey(String tenantid) {
        return null;
    }

    @Override
    @Transactional
    public int updateBasTenant(String tenantid, BasTenant basTenant)  throws RuntimeException {
    	BasTenant oldTenant = this.selectByPrimaryKey(tenantid);

		if(oldTenant != null && StringUtils.isEmpty(basTenant.getParentid()) == false
				&& oldTenant.getParentid().equals(basTenant.getParentid()) == false) {
			BasTenant partentTenant = this.selectByPrimaryKey(basTenant.getParentid());
			if(partentTenant != null) {
				basTenant.setPaths(partentTenant.getPaths() + ConstUtil.TREESPLITTER + basTenant.getTenantid());
			}
		}
		
		//中文全名不能重复
		Example ex = new Example(BasTenant.class);
		ex.or().andEqualTo("fullname",basTenant.getFullname())
		.andIn("status",Arrays.asList(new String[] {"0","2"}))//0=正常,1=已删除,2=锁定, 默认0
		.andNotEqualTo("tenantid",tenantid);
		List<BasTenant> lstRes = basTenantMapper.selectByExample(ex);
		if (lstRes.size() >= 1) {
			throw new BusinessException("000022", basTenant.getFullname());
		}
		
		//中文简称不能重复
		ex = new Example(BasTenant.class);
		ex.or().andEqualTo("shortname",basTenant.getShortname())
		.andIn("status",Arrays.asList(new String[] {"0","2"}))//0=正常,1=已删除,2=锁定, 默认0
				.andNotEqualTo("tenantid",tenantid);
		lstRes = basTenantMapper.selectByExample(ex);
		if (lstRes.size() >= 1) {
			throw new BusinessException("000022", basTenant.getShortname());
		}
		
		if(basTenant.getParentid() == null) {
			basTenant.setParentid("");
		}
		
		this.addUpdUserInfo(basTenant);
		
		ex = new Example(BasTenant.class);
		ex.or().andEqualTo("tenantid",tenantid);
		int ret = basTenantMapper.updateByExample(basTenant, ex);
		//LogInfo.getInstance().addLog(LogMods.bas, Pages.BAS010, LogType.update, "租户更新，租户ID：" + tenantid, LoginUser.getLoginUserInfo());
		return ret;
    }

    @Override
    @Transactional
    public int insertBasTenant(BasTenant basTenant) throws RuntimeException {
    	this.addAddUserInfo(basTenant);
		basTenant.setStatus("0");
		
		if(StringUtils.isEmpty(basTenant.getParentid()) == false) {
			BasTenant partentTenant = this.selectByPrimaryKey(basTenant.getParentid());
			if(partentTenant != null) {
				basTenant.setPaths(partentTenant.getPaths() + ConstUtil.TREESPLITTER  + basTenant.getTenantid());
			}
		}
		
		//中文全名不能重复
		Example ex = new Example(BasTenant.class);
		ex.or().andEqualTo("fullname",basTenant.getFullname())
		.andIn("status",Arrays.asList(new String[] {"0","2"}));//0=正常,1=已删除,2=锁定, 默认0
		List<BasTenant> lstRes = basTenantMapper.selectByExample(ex);
		if (lstRes.size() >= 1) {
			throw new BusinessException("000022", basTenant.getFullname());
		}
		
		//中文简称不能重复
		ex = new Example(BasTenant.class);
		ex.or().andEqualTo("shortname",basTenant.getShortname())
		.andIn("status",Arrays.asList(new String[] {"0","2"}));//0=正常,1=已删除,2=锁定, 默认0
		lstRes = basTenantMapper.selectByExample(ex);
		if (lstRes.size() >= 1) {
			throw new BusinessException("000022", basTenant.getShortname());
		}
		
		if(basTenant.getParentid() == null) {
			basTenant.setParentid("");
		}
		
		int ret = basTenantMapper.insert(basTenant);
		//LogInfo.getInstance().addLog(LogMods.bas, Pages.BAS010, LogType.insert, "租户添加，租户ID：" + basTenant.getTenantid(), LoginUser.getLoginUserInfo());
		return ret;
    }

    @Override
    @Transactional
    public int deleteBasTenant(String tenantid) {
        return 0;
    }
    
    /**
	 * 只在租户模块中使用，因为租户模块中租户ID与其他模块意义不一致
	 * @param entity
	 */
	private <T> void addAddUserInfo(T entity) throws RuntimeException {
		LoginUserInfo loginUserInfo = LoginUser.getLoginUserInfo();
		
		Class<? extends Object> cls = entity.getClass();

		String currTime = DateTime.getCurrDateTime();
		this.setEntityValue(entity,cls,"adduserid",loginUserInfo.getUserId());
		this.setEntityValue(entity,cls,"adduser",loginUserInfo.getUserName());
		this.setEntityValue(entity,cls,"addtime",currTime);
		
		this.setEntityValue(entity,cls,"upduserid",loginUserInfo.getUserId());
		this.setEntityValue(entity,cls,"upduser",loginUserInfo.getUserName());
		this.setEntityValue(entity,cls,"updtime",currTime);
	}
	
	/**
	 * 只在租户模块中使用，因为租户模块中租户ID与其他模块意义不一致
	 * @param entity
	 */
	private <T> void addUpdUserInfo(T entity)  throws RuntimeException {
		LoginUserInfo loginUserInfo = LoginUser.getLoginUserInfo();
		
		Class<? extends Object> cls = entity.getClass();

		this.setEntityValue(entity,cls,"upduserid",loginUserInfo.getUserId());
		this.setEntityValue(entity,cls,"upduser",loginUserInfo.getUserName());
		this.setEntityValue(entity,cls,"updtime",DateTime.getCurrDateTime());
	}
	
	private <T>  void setEntityValue(T entity,Class<? extends Object> cls,String fieldName,String val) throws RuntimeException {
		try {
			String name = String.format("set%s%s", fieldName.substring(0, 1).toUpperCase(), fieldName.substring(1));
			Method method;

			method = cls.getMethod(name, String.class);

			if (method != null) {
				method.invoke(entity, val);
			}
		} 
		catch (NoSuchMethodException e) {
			throw new RuntimeException(e);
		}
		catch (IllegalAccessException | InvocationTargetException e) {
			throw new RuntimeException(e);
		}
	}

}
